package com.wenbing.miio.core;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.Clock;

/**
 * 抽象设备类
 * 从本地服务接口 存取报文
 * 报文的编解码由协议栈负责，协议栈将通过网络接口收发rowData
 * @author wen bing
 * @projectName: miio
 * @package: com.wenbing.miio
 * @className: Device
 * @date 2024/09/19 15:41
 **/
public abstract class Device implements Bootable {

    public static class HardwareConfiguration extends MapContext {

        /**
         * mac地址
         */
        private MacAddress mac;

        /**
         * 硬件模型
         */
        private String model;

        /**
         * 硬件版本
         */
        private String hw_ver;

        /**
         * 唯一属性 uuid
         */
        private String id;

        public MacAddress getMac() {
            return mac;
        }
    }

    protected final Logger LOGGER = LoggerFactory.getLogger(getClass());

    /**
     * 设备时钟
     */
    private Clock clock;

    /**
     * 硬件配置
     */
    private HardwareConfiguration hardwareConfiguration;

    /**
     * 协议栈
     */
    private NetworkStack stack;

    /**
     * 网络接口
     */
    private NetworkInterface networkInterface;

    /**
     * 本地服务接口
     */
    protected NetworkInterface localNetworkInterface;

    public Device(HardwareConfiguration hardwareConfiguration, Clock clock, NetworkInterface networkInterface) {
        this.hardwareConfiguration = hardwareConfiguration;
        this.clock = clock;
        this.networkInterface = networkInterface;
        AsynchronousNetworkStack s = new AsynchronousNetworkStack(this.networkInterface, this.hardwareConfiguration, this.clock);
        this.stack = s;
        this.localNetworkInterface = s;
        initNetworkStack(stack);
    }

    public NetworkStack getNetworkStack() {
        return stack;
    }

    public Clock getClock() {
        return clock;
    }

    public HardwareConfiguration getHardwareConfiguration() {
        return hardwareConfiguration;
    }

    public NetworkInterface getNetworkInterface() {
        return networkInterface;
    }

    @Override
    public void boot() {
        this.networkInterface.boot();
        this.stack.boot();
    }

    /**
     * 引导协议栈
     * @param stack
     */
    public abstract void initNetworkStack(NetworkStack stack);
}
